/**
 * Copyright &copy; 2012-2016 <a href="https://istep.lczyfz.com">Istep</a> All rights reserved.
 */
package com.lczyfz.istep.modules.scene.web;

import com.lczyfz.istep.common.config.Global;
import com.lczyfz.istep.common.constants.SceneConstants;
import com.lczyfz.istep.common.enums.JobStatus;
import com.lczyfz.istep.common.persistence.Page;
import com.lczyfz.istep.common.utils.StringUtils;
import com.lczyfz.istep.common.web.BaseController;
import com.lczyfz.istep.modules.openstack.api.nova.impl.VirtualMachineImpl;
import com.lczyfz.istep.modules.openstack.api.nova.impl.serveraction.ConsolePartImpl;
import com.lczyfz.istep.modules.openstack.api.nova.impl.serveraction.ServerActionsImpl;
import com.lczyfz.istep.modules.openstack.api.nova.model.Server;
import com.lczyfz.istep.modules.openstack.api.nova.model.serveraction.ConsoleIndex;
import com.lczyfz.istep.modules.openstack.api.nova.model.serveraction.ConsoleType;
import com.lczyfz.istep.modules.resource.entity.ResourceCourseware;
import com.lczyfz.istep.modules.resource.service.ResourceCoursewareService;
import com.lczyfz.istep.modules.scene.entity.*;
import com.lczyfz.istep.modules.scene.service.SceneCtfEnvironmentService;
import com.lczyfz.istep.modules.scene.service.SceneEnvironmentInstanceService;
import com.lczyfz.istep.modules.scene.service.SceneEnvironmentService;
import com.lczyfz.istep.modules.sys.entity.ScheduleJob;
import com.lczyfz.istep.modules.sys.service.ScheduleJobService;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * 教学实验环境实例Controller
 * @author dh
 * @version 2017-04-11
 */
@Controller
@RequestMapping(value = "${adminPath}/scene/sceneEnvironmentInstance")
public class SceneEnvironmentInstanceController extends BaseController {
	@Autowired
	private ScheduleJobService scheduleJobService;
	@Autowired
	private SceneEnvironmentInstanceService sceneEnvironmentInstanceService;
	@Autowired
	private SceneCtfEnvironmentService sceneCtfEnvironmentService;
	@Autowired
	private SceneEnvironmentService sceneEnvironmentService;
	@Autowired
	private ResourceCoursewareService resourceCoursewareService;
	@ModelAttribute
	public SceneEnvironmentInstance get(@RequestParam(required=false) String id) {
		SceneEnvironmentInstance entity = null;
		if (StringUtils.isNotBlank(id)){
			entity = sceneEnvironmentInstanceService.get(id);
		}
		if (entity == null){
			entity = new SceneEnvironmentInstance();
		}
		return entity;
	}
	
	@RequiresPermissions("scene:sceneEnvironmentInstance:view")
	@RequestMapping(value = {"list", ""})
	public String list(SceneEnvironmentInstance sceneEnvironmentInstance, HttpServletRequest request, HttpServletResponse response, Model model) {

		Page<SceneEnvironmentInstance> page = sceneEnvironmentInstanceService.findPage(new Page<SceneEnvironmentInstance>(request, response), sceneEnvironmentInstance);

		model.addAttribute("page", page);
		return "modules/scene/sceneEnvironmentInstanceList";
	}
	@RequiresPermissions("scene:sceneEnvironmentInstance:view")
	@RequestMapping(value = "form")
	public String form(SceneEnvironmentInstance sceneEnvironmentInstance, Model model) {
		model.addAttribute("sceneEnvironmentInstance", sceneEnvironmentInstance);
		return "modules/scene/sceneEnvironmentInstanceForm";
	}
	@RequiresPermissions("scene:sceneEnvironmentInstance:view")
	@RequestMapping(value = "sceneTest")
	public String sceneTest() {
		return "modules/scene/sceneTest";
	}
	@RequiresPermissions("scene:sceneEnvironmentInstance:edit")
	@RequestMapping(value = "save")
	public String save(SceneEnvironmentInstance sceneEnvironmentInstance, Model model, RedirectAttributes redirectAttributes) {
		if (!beanValidator(model, sceneEnvironmentInstance)){
			return form(sceneEnvironmentInstance, model);
		}
		sceneEnvironmentInstanceService.save(sceneEnvironmentInstance);
		addMessage(redirectAttributes, "保存教学实验环境实例成功");
		return "redirect:"+Global.getAdminPath()+"/scene/sceneEnvironmentInstance/?repage";
	}
	
	@RequiresPermissions("scene:sceneEnvironmentInstance:edit")
	@RequestMapping(value = "delete")
	public String delete(SceneEnvironmentInstance sceneEnvironmentInstance, RedirectAttributes redirectAttributes) throws Exception{

		try {
			sceneEnvironmentInstanceService.deleteInstance(sceneEnvironmentInstance);
		}catch (Exception e){
			addMessage(redirectAttributes, "删除教学实验环境实例失败");
			return "redirect:"+Global.getAdminPath()+"/scene/sceneEnvironmentInstance/?repage";
		}
		ScheduleJob scheduleJobs= scheduleJobService.findByJobName("env_instance",sceneEnvironmentInstance.getId());
		if(scheduleJobs!=null&&!scheduleJobs.equals(""))
		{
			scheduleJobs.setStatus(JobStatus.Stopped.getValue());
			scheduleJobs.setDelFlag("1");
			scheduleJobService.save(scheduleJobs);
			scheduleJobService.deleteJob(scheduleJobs);
		}
		addMessage(redirectAttributes, "删除教学实验环境实例成功");
		return "redirect:"+Global.getAdminPath()+"/scene/sceneEnvironmentInstance/?repage";
	}

	/**
	 * 进入控制台
	 * @param ids
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value = "console")
	public String console(@RequestParam(required = false) String ids) {

		SceneEnvironmentInstance sceneEnvironmentInstance=sceneEnvironmentInstanceService.get(ids);
//		try{
//			//获取控制台
//			ConsolePartImpl showconsoledemo = new ConsolePartImpl();
//			System.out.println("获取控制台");
//
//			ConsoleType consoletype = new ConsoleType();
//
//
//			consoletype.setType("novnc");
//
//			logger.debug("sceneVmTemplate.getId()===" + sceneEnvironmentInstance.getUrl() + " " + consoletype.getType());
//
//			ConsoleIndex getconsole = showconsoledemo.GetConsole(sceneEnvironmentInstance.getUrl(), consoletype);
//
//			System.out.println("sceneVmTemplate.getId()===" + getconsole.getType() + " " + getconsole.getUrl());
//
//			sceneEnvironmentInstance.setUrl(getconsole.getUrl());
//			sceneEnvironmentInstance.setType(getconsole.getType());
//			sceneEnvironmentInstanceService.save(sceneEnvironmentInstance);
//
//			return getconsole.getUrl();
//		}catch (RuntimeException e){
//			return null;
//		}
		return sceneEnvironmentInstance.getUrl();
	}

	/**
	 * 重启服务器（虚拟机）
	 * @param ids
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value = "rebootServer")
	public String rebootServer(@RequestParam(required = false) String ids) throws Exception{
		logger.debug("dingh===rebootServer=" + ids);
//		SceneEnvironmentInstance sceneEnvironmentInstance=sceneEnvironmentInstanceService.get(ids);
//
//		List<SceneEnvironmentInstanceOs> operateMachine=sceneEnvironmentInstanceService.findOperateMachineByInstanceId(sceneEnvironmentInstance);
//		logger.debug("dingh===VmTemplateId=" + operateMachine.get(0).getVmTemplateId());

		ServerActionsImpl ServerActionsdemo = new ServerActionsImpl();
		ServerActionsdemo.RebootServer(ids);
		boolean getUrl=true;
		while (getUrl)
		{
			logger.debug("dingh===while");

			VirtualMachineImpl virtualMachineImpl=new VirtualMachineImpl();
			Server server=virtualMachineImpl.getServerById(ids,null);
			logger.debug("dingh===while1="+server.getStatus());

			if(server.getStatus().equals("ACTIVE")||server.getStatus().equals("active"))
			{

				//获取控制台
				ConsolePartImpl showconsoledemo = new ConsolePartImpl();
				System.out.println("获取控制台");

				ConsoleType consoletype = new ConsoleType();


				consoletype.setType("novnc");

				ConsoleIndex getconsole = showconsoledemo.GetConsole(server.getId(), consoletype);
				logger.debug("dingh===获取控制台" + getconsole.getUrl() + " " + getconsole.getType());

				//修改表实例url
				sceneEnvironmentInstanceService.instanceVmUpdate(getconsole.getUrl(),ids);
				System.out.println("dingh===获取控制台=" + getconsole.getType() + " " + getconsole.getUrl());
				getUrl=false;
				return getconsole.getUrl();

			}else if(server.getStatus().equals("ERROR")||server.getStatus().equals("ERROR"))
			{
				logger.debug("dingh===获取控制台失败");
				getUrl=false;
			}
			else {
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
		return null;
	}
	/**
	 * 重做实验
	 */
	@ResponseBody
	@RequestMapping(value = "redoExperiment")
	public String redoExperiment(Model model,String instanceId,String environmentId)throws RuntimeException,Exception {
		logger.debug("dingh===redoExperiment=");
		SceneEnvironmentInstance temp=sceneEnvironmentInstanceService.get((instanceId));
		SceneEnvironment sceneEnvironment=sceneEnvironmentService.get(environmentId);
		SceneEnvironmentInstance sceneEnvironmentInstance=new SceneEnvironmentInstance();
		sceneEnvironmentInstance.setCoursewareId(temp.getCoursewareId());

		List<SceneVmTemplate> vmUrlList=new ArrayList<>();
		sceneEnvironmentInstance.setAutoDelete(SceneConstants.AUTO_DELETE_NO);
		sceneEnvironmentInstanceService.deleteInstance(temp);
		sceneEnvironmentService.createInstance(sceneEnvironment, sceneEnvironmentInstance, vmUrlList);

		return sceneEnvironmentInstance.getId();
	}
	/**
	 * 获取实例虚拟机
	 */
	@ResponseBody
	@RequestMapping(value = "getInstanceVm")
	public String getInstanceVm(String vmId){
		logger.debug("dingh===vmId=" + vmId);
		return sceneEnvironmentInstanceService.getInstanceVm(vmId).getConsoleUrl();
	}
	/**
	 * 获取实例虚拟机Url
	 */
	@ResponseBody
	@RequestMapping(value = "getVmUrl")
	public String getVmUrl(String vmId){
		logger.debug("dingh===vmId=" + vmId);
		String url="";
		VirtualMachineImpl virtualMachineImpl=new VirtualMachineImpl();
		Server server=virtualMachineImpl.getServerById(vmId,null);
		if(server.getStatus().equals("ACTIVE")||server.getStatus().equals("active"))
		{

			//获取控制台
			ConsolePartImpl showconsoledemo = new ConsolePartImpl();
			System.out.println("获取控制台");

			ConsoleType consoletype = new ConsoleType();


			consoletype.setType("novnc");

			ConsoleIndex getconsole = showconsoledemo.GetConsole(server.getId(), consoletype);
			logger.debug("dingh===获取控制台" + getconsole.getUrl() + " " + getconsole.getType());

			url=getconsole.getUrl();

			SceneEnvironmentInstanceOs instance=sceneEnvironmentInstanceService.getInstanceVm(vmId);
			if(!instance.getConsoleUrl().equals(url))
			{
				logger.debug("dingh===修改url");
				logger.debug("dingh===instance.getConsoleUrl()="+instance.getConsoleUrl());
				logger.debug("dingh===url="+url);


				sceneEnvironmentInstanceService.instanceVmUpdate(getconsole.getUrl(),vmId);
			}
			//修改表实例url
		}else
		{
			logger.debug("dingh===获取控制台失败，重启虚拟机");
			ServerActionsImpl ServerActionsdemo = new ServerActionsImpl();
			ServerActionsdemo.RebootServer(vmId);
			boolean getUrl=true;
			while (getUrl)
			{
				logger.debug("dingh===while");
				server=virtualMachineImpl.getServerById(vmId,null);
				logger.debug("dingh===while1="+server.getStatus());

				if(server.getStatus().equals("ACTIVE")||server.getStatus().equals("active"))
				{

					//获取控制台
					ConsolePartImpl showconsoledemo = new ConsolePartImpl();
					System.out.println("获取控制台");

					ConsoleType consoletype = new ConsoleType();


					consoletype.setType("novnc");

					ConsoleIndex getconsole = showconsoledemo.GetConsole(server.getId(), consoletype);
					logger.debug("dingh===获取控制台" + getconsole.getUrl() + " " + getconsole.getType());

					url=getconsole.getUrl();
					getUrl=false;

					SceneEnvironmentInstanceOs instance=sceneEnvironmentInstanceService.getInstanceVm(vmId);
					if(!instance.getConsoleUrl().equals(url))
					{
						logger.debug("dingh===修改url");
						sceneEnvironmentInstanceService.instanceVmUpdate(getconsole.getUrl(),vmId);
					}

				}else if(server.getStatus().equals("ERROR")||server.getStatus().equals("ERROR"))
				{
					logger.debug("dingh===获取控制台失败");
					getUrl=false;
				}
				else {
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}

		return url;
	}
	@RequestMapping(value = "toExperimentOperate")
	public String toExperimentOperate(Model model,String instanceId) {

		logger.debug("dingh===instanceId==="+instanceId+"　");
		SceneEnvironmentInstance sceneEnvironmentInstance=sceneEnvironmentInstanceService.get(instanceId);

		ResourceCourseware resourceCourseware=resourceCoursewareService.get(sceneEnvironmentInstance.getCoursewareId());
		SceneEnvironment sceneEnvironment=sceneEnvironmentService.get(sceneEnvironmentInstance.getEnvironmentId());


		String document="";
		String coursewareName="";

		if(resourceCourseware!=null&&!resourceCourseware.equals(""))
		{
			document=resourceCourseware.getDocument();
			coursewareName=resourceCourseware.getCoursewareName();

		}

//		List<SceneEnvironmentInstanceOs> vmList=sceneEnvironmentInstanceService.findVmTemplateListByInstanceId(sceneEnvironmentInstance);
//		logger.debug("dingh===vm数量=" + vmList.size());
		List<SceneEnvironmentInstanceOs> vmList=sceneEnvironmentInstanceService.findOperateMachineByInstanceId(sceneEnvironmentInstance);
		logger.debug("dingh===vm数量=" + vmList.size());

		if(vmList.size()>0)
		{
			sceneEnvironmentInstance.setInstanceOsList(vmList);
		}
		Date orderTime=sceneEnvironmentInstance.getEndDate();
		Calendar ca = Calendar.getInstance();//得到一个Calendar的实例
		ca.setTime(orderTime); //设置时间为当前时间
		int year = ca.get(Calendar.YEAR);//获取年份
		int month=ca.get(Calendar.MONTH)+1;//获取月份
		int day=ca.get(Calendar.DATE);//获取日
		int hour=ca.get(Calendar.HOUR_OF_DAY);//小时
		int minute=ca.get(Calendar.MINUTE);//分
		int second=ca.get(Calendar.SECOND);//秒    2017/05/16 20:27:30
		//"30 10 1 20 10 ? 2011" 2011年10月20号1点10分30秒触发任务
		String endTime=year+"/"+month+"/"+day+" "+hour+":"+minute+":"+second;



//		List<SceneEnvironmentInstanceOs> vmList=sceneEnvironmentInstanceService.findVmTemplateListByInstanceId(sceneEnvironmentInstance);

		logger.debug("dingh===结束时间=" + endTime);
		model.addAttribute("coursewareName", coursewareName);
		model.addAttribute("endTime",endTime);
		model.addAttribute("resourceCourseware",resourceCourseware);
		model.addAttribute("sceneEnvironment", sceneEnvironment);
		model.addAttribute("sceneEnvironmentInstance", sceneEnvironmentInstance);
		model.addAttribute("vmList", vmList);

		return "modules/scene/sceneExperimentOperation";
	}
	/**
	 * 结束实验
	 * @param instanceId
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value = "endExperiment")
	public String endExperiment(@RequestParam(required = false) String instanceId) throws RuntimeException,Exception{
		logger.debug("dingh===endExperiment=1aaa22" + instanceId);
//		instanceId="836621ecc0af4289a6d7a2eeb35d04cf";
		SceneEnvironmentInstance sceneEnvironmentInstance=sceneEnvironmentInstanceService.get(instanceId);
		ScheduleJob scheduleJobs= scheduleJobService.findByJobName("env_instance",instanceId);
		if(scheduleJobs!=null&&!scheduleJobs.equals(""))
		{
			scheduleJobs.setStatus(JobStatus.Stopped.getValue());
			scheduleJobs.setDelFlag("1");
			scheduleJobService.save(scheduleJobs);
			scheduleJobService.deleteJob(scheduleJobs);
		}
		if(sceneEnvironmentInstance!=null&&!sceneEnvironmentInstance.equals(""))
		{
			sceneEnvironmentInstanceService.deleteInstance(sceneEnvironmentInstance);

		}

		return  null;
	}
	/**
	 * 查看拓扑
	 * @param environmentId
	 * @return
	 */
	@RequestMapping(value = "topologyShow")
	public String topologyShow(String environmentId,Model model) {
		logger.debug("dingh===topologyShow=" + environmentId);
		SceneEnvironment sceneEnvironment=sceneEnvironmentService.get(environmentId);
		if(sceneEnvironment.getTopologyXml()!=null&&!sceneEnvironment.getTopologyXml().equals("")) {
			String str = sceneEnvironment.getTopologyXml().replace("\"", "\\\"");
			sceneEnvironment.setTopologyXml(str);
		}
		logger.debug("saveTopology===1113" + sceneEnvironment.getTopologyXml());
		model.addAttribute("sceneEnvironment", sceneEnvironment);
		model.addAttribute("stuOperate", "yes");

		return "modules/scene/sceneEnvironmentTopology";
	}
	/**
	 * 查看ctf拓扑
	 * @param environmentId
	 * @return
	 */
	@RequestMapping(value = "ctfTopologyShow")
	public String ctfTopologyShow(String environmentId,Model model) {
		logger.debug("dingh===ctfTopologyShow=" + environmentId);
		SceneCtfEnvironment sceneCtfEnvironment=sceneCtfEnvironmentService.get(environmentId);
		if(sceneCtfEnvironment.getTopologyXml()!=null&&!sceneCtfEnvironment.getTopologyXml().equals("")) {
			String str = sceneCtfEnvironment.getTopologyXml().replace("\"", "\\\"");
			sceneCtfEnvironment.setTopologyXml(str);
		}
		logger.debug("saveTopology===1113" + sceneCtfEnvironment.getTopologyXml());
		model.addAttribute("sceneCtfEnvironment", sceneCtfEnvironment);
		model.addAttribute("stuOperate", "yes");

		return "modules/scene/sceneCtfEnvironmentTopology";
	}
	/**
	 * 全屏
	 * @param fullScreenConsoleUrl
	 * @return
	 */
	@RequiresPermissions("scene:sceneEnvironmentInstance:view")
	@RequestMapping(value = "fullScreenConsole")
	public String fullScreenConsole(String fullScreenConsoleUrl,Model model) {
		logger.debug("dingh===fullScreenConsoleUrl=" + fullScreenConsoleUrl);
		model.addAttribute("fullScreenConsoleUrl", fullScreenConsoleUrl);
		return "modules/scene/sceneExperimentFullScreenConsole";
	}
}